package com.partvoyage.client.mvp2.view.carte.service;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.geocode.DirectionQueryOptions;
import com.google.gwt.maps.client.geocode.DirectionQueryOptions.TravelMode;
import com.google.gwt.maps.client.geocode.DirectionResults;
import com.google.gwt.maps.client.geocode.Directions;
import com.google.gwt.maps.client.geocode.DirectionsCallback;
import com.google.gwt.maps.client.geocode.StatusCodes;
import com.google.gwt.maps.client.geocode.Waypoint;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.partvoyage.client.mvp2.view.carte.bean.RouteBean;
import com.partvoyage.client.outil.PointSurLaCarte;
import com.partvoyage.client.service.infopoint.InfoPointService;
import com.partvoyage.client.service.infopoint.InfoPointServiceAsync;
import com.partvoyage.client.sessionClient.SessionClient;
import com.partvoyage.shared.Constants;
import com.partvoyage.shared.InfoPointBean;
import com.partvoyage.shared.InfoPointBean.TYPE_ZOOM_LEVEL;

public class CartePresentationService {
	private static final InfoPointServiceAsync infoService = GWT
			.create(InfoPointService.class);

	public static TYPE_ZOOM_LEVEL getZoomLevel(Integer zoomlevel) {
		if (zoomlevel <= 6) {
			return TYPE_ZOOM_LEVEL.PAYS_LEVEL;
		} else if (zoomlevel > 6 && zoomlevel < 13) {
			return TYPE_ZOOM_LEVEL.VILLE_LEVEL;
		} else {
			return TYPE_ZOOM_LEVEL.ADRESSE_LEVEL;
		}
	}

	public static PointSurLaCarte getPointSurLaCarteFromListe(
			InfoPointBean infoPointBean) {
		if (infoPointBean == null) {
			return null;
		}
		for (PointSurLaCarte pointSurLaCarte : SessionClient.getInstance()
				.getPointSurLaCartes()) {
			if (pointSurLaCarte.getInfo().getMarkerId()
					.equals(infoPointBean.getMarkerId())) {
				return pointSurLaCarte;
			}
		}
		return null;

	}

	public static InfoPointBean getInfoPointBeanDestinationFromListe(
			List<InfoPointBean> list, InfoPointBean infoPointBeanToSearch) {
		if (infoPointBeanToSearch == null) {
			return null;
		}
		for (InfoPointBean infoPointBean : list) {
			if (infoPointBean.getMarkerId().equals(
					infoPointBeanToSearch.getMarkerIdDestination())) {
				return infoPointBean;
			}
		}
		return null;

	}

	public static void creerRoute(MapWidget map, final PointSurLaCarte source,
			final PointSurLaCarte destination) {
		DirectionQueryOptions opts = new DirectionQueryOptions(map);
		if (source.getInfo().getComment().equals(Constants.COMMENT_A_PIED)) {
			opts.setTravelMode(TravelMode.WALKING);
		} else {
			opts.setTravelMode(TravelMode.DRIVING);
		}
		Waypoint[] waypoints = new Waypoint[2];
		waypoints[0] = new Waypoint(source.getLatLng());
		waypoints[1] = new Waypoint(destination.getLatLng());
		// Affichage de la route
		Directions.loadFromWaypoints(waypoints, opts, new DirectionsCallback() {

			public void onFailure(int statusCode) {
				Window.alert("Failed to load directions: Status "
						+ StatusCodes.getName(statusCode) + " " + statusCode);
			}

			public void onSuccess(final DirectionResults directionResults) {
				InfoPointBean infoBeanSource = source.getInfo();
				InfoPointBean infoBeanDestination = destination.getInfo();
				infoBeanSource.setMarkerIdDesination(infoBeanDestination
						.getMarkerId());
				// mise à jour du bean source avec destination
				infoService.update(infoBeanSource,
						new AsyncCallback<InfoPointBean>() {

							@Override
							public void onSuccess(InfoPointBean infoPointBean) {
								// ajout de la route dans la session
								SessionClient.getInstance().addRoute(source,
										destination, directionResults);
								SessionClient.getInstance().setSourcePourRoute(
										null);
							}

							@Override
							public void onFailure(Throwable caught) {
								// TODO Auto-generated method stub
							}
						});
			}
		});

	}

	public static void nettoyageRoutes() {
		for (RouteBean routeBean : SessionClient.getInstance()
				.getRouteSetBean().getRouteBeans()) {
			routeBean.getDirectionResult().clear();
		}
		SessionClient.getInstance().getRouteSetBean().reset();
	}
	// private class GestionDirection {
	//
	// private DirectionQueryOptions opts = null;
	// private Map<Integer, PointSurLaCarte> pointSurLaCartes = null;
	// private List<DirectionResults> listDirections = null;
	// private Integer compteur = null;
	//
	// public GestionDirection() {
	// opts = new DirectionQueryOptions(display.getMap());
	// pointSurLaCartes = new TreeMap<Integer, PointSurLaCarte>();
	// listDirections = new ArrayList<DirectionResults>();
	// compteur = 0;
	// }
	//
	// public void ajouterPointEtDessiner(PointSurLaCarte pointSurLaCarte) {
	// // ajout du point dans la liste
	// pointSurLaCartes.put(compteur, pointSurLaCarte);
	// //
	// if (compteur > 1) {
	// List<PointSurLaCarte> pointSurLaCartesADessiner = new
	// LinkedList<PointSurLaCarte>();
	// pointSurLaCartesADessiner.add(pointSurLaCartes
	// .get(compteur - 1));
	// pointSurLaCartesADessiner.add(pointSurLaCarte);
	// dessinerTousLesPointsDeLaListe(pointSurLaCartesADessiner);
	// }
	// //
	// compteur++;
	// }
	//
	// public void nettoyagePoints() {
	// for (DirectionResults directionResults : listDirections) {
	// directionResults.clear();
	// }
	// listDirections.clear();
	// pointSurLaCartes.clear();
	// compteur = 0;
	// }
	//
	// public void dessinerTousLesPoints() {
	// List<PointSurLaCarte> pointSurLaCartesADessiner = new
	// LinkedList<PointSurLaCarte>(
	// this.pointSurLaCartes.values());
	// dessinerTousLesPointsDeLaListe(pointSurLaCartesADessiner);
	// }
	//
	// private void dessinerTousLesPointsDeLaListe(
	// List<PointSurLaCarte> pointSurLaCartesADessiner) {
	// if (pointSurLaCartesADessiner == null
	// || pointSurLaCartesADessiner.size() <= 1) {
	// return;
	// }
	// Waypoint[] waypoints = new Waypoint[pointSurLaCartesADessiner
	// .size()];
	// int i = 0;
	// for (PointSurLaCarte pointSurLaCarte : pointSurLaCartesADessiner) {
	//
	// Waypoint wayPoint = new Waypoint(pointSurLaCarte.getLatLng());
	// waypoints[i++] = wayPoint;
	// }
	// Directions.loadFromWaypoints(waypoints, opts,
	// new DirectionsCallback() {
	//
	// public void onFailure(int statusCode) {
	// Window.alert("Failed to load directions: Status "
	// + StatusCodes.getName(statusCode) + " "
	// + statusCode);
	// }
	//
	// public void onSuccess(DirectionResults result) {
	// // TODO lier destination et source
	// listDirections.add(result);
	// }
	// });
	// }
	//
	// }
}
